<?php
/**
 * DynaGrid - The PHP datagrid
 *
 * @package    DynaGrid
 * @author     $Author: keesschepers $
 * @version    $Id: Default.php 12 2011-02-12 00:33:20Z keesschepers $
 */

include_once 'PageBrowser/Interface.php';

final class DynaGrid_PageBrowser_Default implements DynaGrid_PageBrowser_Interface {
	public static $lblPrevious = 'Previous';
	public static $lblNext = 'Next';
	public static $lblGlobal = 'Page';

	/**
	 * Limit of items on a page
	 *
	 * @var integer
	 */
	private $limit=0;
	/**
	 * Total amount of records available for the list the parent object is drawing
	 *
	 * @var integer
	 */
	private $totalRecords=0;
	/**
	 * Calculated number of pages available for parent's data
	 *
	 * @var integer
	 */
	private $pages=0;
	/**
	 * To avoid too many numbers being displayed, you can use a offset like google (...5678...) instead
	 * of 12345678.
	 *
	 * @var integer
	 */
	private $browseOffset=8;
	/**
	 * Current page the user is browsing
	 *
	 * @var integer
	 */
	private $pageNumber=0;
	/**
	 * URL object, to modify or display the correct url
	 *
	 * @var DynaGrid_Url
	 */
	private $url;
	/**
	 *
	 * @var string Argument which is used for determing which page nr we are.
	 */
	private $pageArgument;
	/**
	 * Constructor
	 *
	 * @param DynaGrid_Url $url
	 * @param string $pageArgument Which GET argument is used for determining which pagenr we are
	 * @param array $labels An associative array with keys previous, next and page with value as label
	 */
	public function __construct(DynaGrid_Url &$url, $pageArgument='pagenr', $labels = array()) {
		$this->pageNumber = $url->pagenr;
		$this->url = $url;
		$this->pageArgument = $pageArgument;

		/**
		 * Set the labels for rendering the pagebrowser
		 */
		if(is_array($labels) && count($labels) > 2) {
			foreach($labels as $key=>$label) {
				switch($key) {
					case 'previous' :
						self::$lblPrevious = $label;
						break;
					case 'next' :
						self::$lblNext;
						break;
					case 'page' :
						self::$lblGlobal = $label;
						break;
				}
			}
		}
	}
	/**
	 * Set the limit of "items" per page
	 *
	 * @param integer $limit
	 */
	public function setLimit($limit) {
		$this->limit = (int)$limit;
	}
	/**
	 * The total amount of "items" available
	 *
	 * @param integer $totalRecords
	 */
	public function setTotalRecords($totalRecords) {
		$this->totalRecords = (int)$totalRecords;
	}
	public function setBrowseOffset($browseoffset) {
			$this->browseOffset = $browseoffset>0 ? (int)$browseoffset : 8;
	}
	/**
	 * Set the current page user is visiting
	 *
	 * @param integer $currentPage
	 */
	public function setCurrentPage($currentPage) {
		$this->pageNumber = (int)$currentPage;
	}
	public function getCurrentPage() {
		return $this->pageNumber;
	}
	/**
	 * Get the previous "button"
	 *
	 * @return string HTML
	 */
	private function getPrevious() {
		$str = '';

		$url = clone $this->url;
		$url->pagenr = ($url->pagenr-1);

		$str .= '<div class="browserleft">';
		$str .= '<a href="'.$url->getQueryString().'" ';
		$str .= 'title="'.self::$lblPrevious.' &laquo;" ';
		$str .= '>'.self::$lblPrevious;
		$str .= '</a>';
		$str .= '</div>';
		return $str;
	}
	/**
	 * Get the next "button"
	 *
	 * @return string HTML
	 */
	private function getNext() {
		$str = '';

		$url = clone $this->url;
		$url->pagenr = ($url->pagenr+1);

		$str .= '<div class="browserright">';
		$str .= '<a href="'.$url->getQueryString().'" ';
		$str .= 'title="'.self::$lblNext.' &raquo;" ';
		$str .= '>'.self::$lblNext;
		$str .= '</a>';
		$str .= '</div>';
		return $str;
	}
	/**
	 * Creates the HTML for a part of the page browser (a iteration) and returns it's HTML.
	 *
	 * @param integer $pagenr
	 * @param string $innerHTML will be replaced with the iteration if set
	 * @return string HTML
	 */
	private function renderPageNumber($pagenr,$innerHTML='') {
		$str ='';

		$url = clone $this->url;
		$url->pagenr = $pagenr;

		$str .= '<span>';
		$str .= '<a href="'.$url->getQueryString().'" ';
		$str .= 'title="'.ucfirst(self::$lblGlobal).': '.($pagenr+1).'" ';
		$str .= 'class="'.(($pagenr == $this->pageNumber) ? 'pageBrowserSelected' : 'pageBrowser').'" ';
		$str .= '>';
		$str .= ((strlen($innerHTML)>0) ? $innerHTML : ($pagenr+1));
		$str .= '</a>';
		$str .= '</span>';
		return $str;
	}
	/**
	 * Proces all functionality of the page browser and return a HTML string
	 *
	 * @return string HTML
	 */
	private function process() {
		if($this->totalRecords > 0 && $this->limit > 0){
			$this->pages = ceil($this->totalRecords / $this->limit);
		}

		$str = '<div class="pagebrowser">';

		/**
		 * Previous button
		 */
		if($this->pageNumber > 0){
			$str .= $this->getPrevious();
		}else{
			$str .= '<div class="browserleft">&nbsp;</div>' ;
		}
		$str .= '<div class="browsermiddle">';

		$start = ($this->pageNumber>($this->browseOffset/2)) ? ceil($this->pageNumber-($this->browseOffset/2)) : 0;
		$end = (($this->pageNumber+($this->browseOffset/2)) < $this->pages) ? ceil($this->pageNumber+($this->browseOffset/2)) : $this->pages;

		if($this->pages>0)
			$str .= $this->renderPageNumber(0,'&laquo;');

		for($pagenr=$start; $pagenr<$end; $pagenr++) {
			$str .= ' '.$this->renderPageNumber($pagenr).' ';
		}

		if($this->pages>0)
			$str .= $this->renderPageNumber(($this->pages-1),'&raquo;');

		$str .= '</div>';
		/**
		 * Next button
		 */
		if($this->pageNumber < ($this->pages-1)){
			$str .= $this->getNext();
		} else {
			$str .= '<div class="browserright">&nbsp;</div>';
		}

		$str .= '<div class="spacer"></div>';
		$str .= '</div>';
		return $str;
	}
	/**
	 * Function according to the interface which should return HTML content
	 *
	 * @return string HTML
	 */
	public function getHTML() {
		return $this->process();
	}
}

?>
